
package org.linlinjava.litemall.wx.web;

import org.linlinjava.litemall.core.storage.StorageService;
import org.linlinjava.litemall.core.util.CharUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LitemallStorage;
import org.linlinjava.litemall.db.service.LitemallStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * 对象存储服务
 */
@RestController
@RequestMapping("/wx/storage")
@Validated
public class WxStorageController {

	@Autowired
	private StorageService storageService;

	@Autowired
	private LitemallStorageService litemallStorageService;

	@SuppressWarnings("unused")
	private String generateKey(String originalFilename) {
		int index = originalFilename.lastIndexOf('.');
		String suffix = originalFilename.substring(index);
		String key = null;
		LitemallStorage storageInfo = null;
		do {
			key = CharUtil.getRandomString(20) + suffix;
			storageInfo = litemallStorageService.findByKey(key);
		} while (storageInfo != null);
		return key;
	}

	@PostMapping("/upload")
	public Object upload(@RequestParam("file") MultipartFile file) throws IOException {
		String originalFilename = file.getOriginalFilename();
		LitemallStorage litemallStorage = storageService.store(file.getInputStream(),
			file.getSize(),
			file.getContentType(),
			originalFilename);
		return ResponseUtil.ok(litemallStorage);
	}

	/**
	 * 访问存储对象
	 *
	 * @param key 存储对象key
	 * @return
	 */
	@GetMapping("/fetch/{key:.+}")
	public ResponseEntity<Resource> fetch(@PathVariable String key) {
		LitemallStorage litemallStorage = litemallStorageService.findByKey(key);
		if (key == null) {
			return ResponseEntity.notFound().build();
		}
		if (key.contains("../")) {
			return ResponseEntity.badRequest().build();
		}
		String type = litemallStorage.getType();
		MediaType mediaType = MediaType.parseMediaType(type);
		Resource file = storageService.loadAsResource(key);
		if (file == null) {
			return ResponseEntity.notFound().build();
		}
		return ResponseEntity.ok().contentType(mediaType).body(file);
	}

	/**
	 * 访问存储对象
	 *
	 * @param key 存储对象key
	 * @return
	 */
	@GetMapping("/download/{key:.+}")
	public ResponseEntity<Resource> download(@PathVariable String key) {
		LitemallStorage litemallStorage = litemallStorageService.findByKey(key);
		if (key == null) {
			return ResponseEntity.notFound().build();
		}
		if (key.contains("../")) {
			return ResponseEntity.badRequest().build();
		}
		String type = litemallStorage.getType();
		MediaType mediaType = MediaType.parseMediaType(type);
		Resource file = storageService.loadAsResource(key);
		if (file == null) {
			return ResponseEntity.notFound().build();
		}
		return ResponseEntity
			.ok()
			.contentType(mediaType)
			.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
			.body(file);
	}
}